import 'dart:async';
import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../../bean/home_bean.dart';
import '../../common/data_source.dart';
import '../../common/system_config.dart';
import '../../model/initapp_model.dart';
import '../../utils/tools/analysis_code.dart';
import '../../utils/tools/createwebsocket_tool.dart';
import '../../utils/tools/localstorage_tool.dart';
import '../../utils/tools/screenutil_tool.dart';
import '../../utils/widget/appbar_widget.dart';
import '../../utils/widget/fixedtip_widget.dart';
import '../../utils/widget/nodata_widget.dart';
import '../../viewmodel/home_vm.dart';
import 'components/alarmnumer_widget.dart';
import 'components/columnitem_widget.dart';
import 'methods/format_data.dart';

class HomeView extends StatefulWidget {
  @override
  HomeView({Key key, this.callBack}) : super(key: key);
  final Function callBack;

  HomeViewState createState() => new HomeViewState();
}

class HomeViewState extends State<HomeView> {
  // 页面是否完成加载
  bool isCompleteLoad = false;

  // 台区信息
  Map equipmentInfo;

  // 服务端响应的数据
  HomeBean pageData;

  // 存储ws对象
  MyWebSocket instanceWebSocket;

  // 存储ws定时器
  Timer wsTimer;

  // 网络状态
  bool networkstate;

  // 标记当前app的状态（特指：异常情况0：网络异常  1：WebSocket已断开   2：重连WebSocket）
  int componentState;

  // * 统计各项函数被执行的次数
  // 1、网络监听首次进入页面时为：false（无法网络是否通畅），将为执行未接通的“行为处理”。
  //   因WebSocket中有重连机制，当网络转为正常时会导致拿到数据且不断尝试重连的bug
  // 2、网络监听在builder函数中会被多次触发，但已有的函数都只需要执行一次。
  // 综上所属需要对组件执行次数进行统计并作为判断条件
  int implementCount = 0;

  // 标记是否正常关闭Websocket
  // 其中跳转路由属于正常关闭，其他均属于异常关闭
  bool normalShutdownWebsocket = false;

  // 组件选块对应跳转的路由路径
  List<String> ls = [
    "/voiceprintmonitorview",
    "/dropswitchview",
    "/wirelesstmview",
    "/envmonitoringview",
    "/waterinvasionview"
  ];

  // 设备可视区的宽高
  double _mediaWidth;
  double _mediaHeight;

  @override
  Widget build(BuildContext context) {
    // 获取设备的宽高
    _mediaWidth = MediaQuery.of(context).size.width;
    _mediaHeight = MediaQuery.of(context).size.height;

    return Scaffold(
      appBar: AppBarWidget("信息总览").build(context),
      body: Consumer<InitAppModel>(
        builder: (context, model, child) {
          // 将网络状态存储为全局状态，便于其他函数访问。（该状态会实时更新）
          networkstate = model.networkstate;

          // 必须保证网络通畅
          if (networkstate) {
            // 标记网络已恢复
            componentState = null;

            // 检查是否为初始化状态
            if (implementCount <= 0) {
              // 发起网络请求，获取页面数据
              initPage(context);

              // 开启WebSocket
              initWebSocket();

              // 统计执行次数
              implementCount++;
            }
          } else {
            // 标记网络异常
            componentState = 0;

            if (implementCount > 0 && !normalShutdownWebsocket) {
              // 还原组件初始化状态
              implementCount = 0;
            }
          }

          // 绘制组件
          return Container(
            width: double.infinity,
            child: Stack(
              children: [
                isCompleteLoad
                    ? Padding(
                        padding: EdgeInsets.only(
                            top: model.networkstate ? 0 : ST.seth(76)),
                        child: SingleChildScrollView(
                          child: Column(
                            children: [
                              Container(
                                child: Padding(
                                  padding: EdgeInsets.symmetric(
                                      vertical: ST.seth(16),
                                      horizontal: ST.setw(32)),
                                  child: InkWell(
                                    onTap: () =>
                                        widget.callBack({"currentIndex": 1}),
                                    child: Container(
                                      width: double.infinity,
                                      padding: EdgeInsets.symmetric(
                                          vertical: ST.seth(40),
                                          horizontal: ST.setw(32)),
                                      decoration: BoxDecoration(
                                          color:
                                              Theme.of(context).backgroundColor,
                                          borderRadius: BorderRadius.all(
                                              Radius.circular(8)),
                                          boxShadow: [
                                            BoxShadow(
                                                offset: Offset(0, 2), //x,y轴
                                                color:
                                                    Color.fromRGBO(0, 0, 0, .1),
                                                blurRadius: 3 //投影距离
                                                )
                                          ]),
                                      child: Row(
                                        children: [
                                          Expanded(
                                              child: Column(
                                            mainAxisAlignment:
                                                MainAxisAlignment.start,
                                            crossAxisAlignment:
                                                CrossAxisAlignment.start,
                                            children: [
                                              Container(
                                                width: double.infinity,
                                                color: Theme.of(context)
                                                    .backgroundColor,
                                                margin: EdgeInsets.only(
                                                    bottom: ST.seth(10)),
                                                child: Text(
                                                  '当前台区：${equipmentInfo != null ? equipmentInfo["equipmentName"] : "全国"}',
                                                  style: TextStyle(
                                                      fontSize: SystemConfig
                                                          .fs_title3),
                                                ),
                                              ),
                                              pageData != null
                                                  ? AlarmNumerWidget(
                                                      num: pageData.alarmAmount)
                                                  : SizedBox.shrink()
                                            ],
                                          )),
                                          Icon(
                                            Icons.chevron_right,
                                            color: SystemConfig.grayColor,
                                          )
                                        ],
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                              Container(
                                width: double.infinity,
                                margin: EdgeInsets.only(bottom: ST.setw(32)),
                                child: Wrap(
                                  runSpacing: ST.setw(32),
                                  children: crateItemContainer(5),
                                ),
                              )
                            ],
                          ),
                        ),
                      )
                    : NoData(),
                componentState == null
                    ? SizedBox.shrink()
                    : Positioned(
                        top: 0,
                        left: 0,
                        right: 0,
                        child: FixedTopWidget(componentState),
                      ),
              ],
            ),
          );
        },
      ),
    );
  }

  /// 绘制Container组件
  /// * [len] int|必填|循环的长度
  List<Widget> crateItemContainer(int len) {
    List<Widget> lw = [];
    for (int i = 0; i < len; i++) {
      lw.add(
        Container(
          decoration: BoxDecoration(
            color: Theme.of(context).backgroundColor,
            borderRadius: BorderRadius.all(Radius.circular(8)),
            boxShadow: [
              BoxShadow(
                offset: Offset(0, 3), //x,y轴
                color: Color.fromRGBO(0, 0, 0, .1),
                blurRadius: 3, //投影距离
              )
            ],
          ),
          width: (_mediaWidth - ST.setw(32) * 3) / 2,
          height: _mediaHeight * .2,
          margin: EdgeInsets.only(left: ST.setw(32)),
          child: MaterialButton(
            onPressed: () => _responseReturnBehavior(context, ls[i]),
            child: createContent(i),
          ),
        ),
      );
    }
    return lw;
  }

  /// 绘制内容
  /// * [index] int|必填|下标
  Widget createContent(int index) {
    Widget w;
    w = Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        //Text("123123123"),
        ColumnItemWidget(pageData.moduleList[index].tempList),
        SizedBox(
          height: ST.seth(2),
          width: ST.setw(280),
          child: Container(
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.centerLeft,
                end: Alignment(1, 0),
                colors: [
                  const Color(0xFFFFFFFF),
                  const Color(0xFFbbbbbb),
                  const Color(0xFFFFFFFF),
                ], // whitish to gray
              ),
            ),
          ),
        ),
        Container(
          height: ST.seth(70),
          alignment: Alignment.center,
          child: Text(
            "${analysisCode(int.parse(pageData.moduleList[index].moduleType), equipmentTypeSourceData)['value']}",
            style: TextStyle(fontSize: SystemConfig.fs_title3),
          ),
        )
      ],
    );
    return w;
  }

  /// 初始化页面
  /// * [context] 必填|上下文
  void initPage(BuildContext context) async {
    // 读取台区信息
    equipmentInfo =
        json.decode(await LocalStorage.getStringItem("equipmentInfo"));

    // 获取告警信息
    HomeBean res = await HomeVM().getAlarmInfo(
        context, {"equipmentId": equipmentInfo["equipmentId"]},
        title: "正在初始化");

//    print("------");
//    print(res);

    // 渲染页面
    if (res != null) {
      setState(() {
        componentState = null;
        isCompleteLoad = true;
        pageData = formatData(res, filterTimer: ["4"]);
      });
    } else {
      setState(() {
        isCompleteLoad = false;
      });
    }
  }

  /// 初始化WebSocket
  void initWebSocket() async {
    String token = await LocalStorage.getStringItem("token");
    String url = "appAlarmStatistics/${token}/${equipmentInfo['equipmentId']}";

    instanceWebSocket = new MyWebSocket(url, onMessage: (dynamic result) {
      // 接通websocket数据后修改componentState
      if (componentState != null) {
        setState(() {
          componentState = null;
        });
      }

      // 将Websocket中获取的数据赋值pageData
      if (pageData != null && result != "pong") {
        print("收到数据了");
        setState(() {
          pageData = formatData(
              HomeBean(result["data"]["alarmAmount"], result["data"]["value"]),
              filterTimer: ["4"]);
        });
      }
    }, onError: (error) {
      print("websocket错误了");
    }, onDone: () {
      if (networkstate && !normalShutdownWebsocket && implementCount > 0) {
        // 标记websocket已经断开
        setState(() {
          componentState = 1;
        });

        // 设置5s重连
        wsTimer = Timer(Duration(seconds: 5), () {
          instanceWebSocket.openSocket();
        });
      }
    });
  }

  /// 路由返回的回调
  /// * [context] 必填 |上下文
  /// * [index] 必填|int|下标
  void _responseReturnBehavior(BuildContext context, String url) {
    // 标记：正常关闭 websocket，不需要开启自动重连
    normalShutdownWebsocket = true;

    // 标记：组件被执行次数。此处implementCount的值只需要大于0即可。
    // 防止“离开组件”但是“组件未被销毁”情况下，网络断开后implementCount会被赋值为0，当再次连接上网络时会执行初始化中所有的函数。
    // 解决：“离开组件”时将implementCount赋值大于0的数据。
    //
    implementCount = 100;

    // 关闭已开启的定时器及websocket
    if (wsTimer != null) wsTimer.cancel();
    if (instanceWebSocket != null) instanceWebSocket.closeSocket();

    // 返回组件的回调
    Navigator.pushNamed(context, url).then((value) {
      // 标记：websocket状态需要开启自动重连
      normalShutdownWebsocket = false;

      // 网络通畅情况下开启websocket，反之将implementCount赋值为：0
      // 情况一：网络正常
      // 只需开启websocket即可
      // 情况二：网络异常
      // 需要将implementCount赋为：0，等待网络正常自行执行初始化中的所有函数
      if (networkstate) {
        initWebSocket();
      } else {
        implementCount = 0;
      }
    });
  }

  @override
  void dispose() {
    super.dispose();

    normalShutdownWebsocket = true;

    if (wsTimer != null) wsTimer.cancel();

    if (instanceWebSocket != null) instanceWebSocket.closeSocket();

    implementCount = null;
  }
}
